package de.koller.nature.render;

import de.koller.nature.NNode;
import de.koller.nature.render.obj.Tile;
import de.koller.oceanFramework.gl.util.TextureUtil;
import de.koller.oceanFramework.gl.util.ViewUtil;
import de.koller.oceanFramework.tree.Child;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;

public class NRender extends NNode {

	@Child public final Textures textures = new Textures();
	public static final Random rnd = new Random();
	
	private Tile[][] tile = new Tile[100][100];
	private float[][] heightMap = new float[101][101];
	private float rotation = 0;
	
	@Override
	protected void init() {
		super.init();
		
		ViewUtil.initPerspective();
		
//		GL11.glEnable( GL11.GL_CULL_FACE );
//		GL11.glCullFace( GL11.GL_BACK );

		GL11.glEnable( GL11.GL_DEPTH_TEST );
		GL11.glDepthFunc( GL11.GL_LEQUAL );
		
		GL11.glAlphaFunc( GL11.GL_GREATER, 0.1f );
		GL11.glEnable( GL11.GL_ALPHA_TEST );
	}

	@Override
	protected void postChildInit() {
		super.postChildInit();
	
		fillHeight();
		
		for( int x = 0; x < 100; x++ )
			for( int y = 0; y < 100; y++ )
				tile[x][y] = new Tile( x, y, heightMap );

	}
	
	private void fillHeight() {
		final int fw = 101, fh = 101;
		final int checkSize = 64;
		
		final int[][] tp = new int[ fw + 2*checkSize ][ fh + 2*checkSize ];
		final int[][] th = new int[ fw ][ fh ];
		
		for( int x = 0; x < tp.length; x++ )
			for( int y = 0; y < tp[0].length; y++ ) {
				int t = rnd.nextInt( 2 );
				tp[x][y] = t;
				
				//if( x < checkSize || y < checkSize || x > tp.length-checkSize || y > tp[0].length-checkSize  )
				//	tp[x][y] = 1;
			}
		
		ExecutorService s = Executors.newFixedThreadPool( 4 );
		
		for( int x = 0; x < fw; x++ ) {
			final int xv = x;
			s.execute( new Runnable() {
				@Override public void run() {
					for( int y = 0; y < fh; y++ ) {
						for( int dx = -checkSize; dx < checkSize; dx++ )
							for( int dy = -checkSize; dy < checkSize; dy++ ) {
								double dis = Math.sqrt( dx*dx + dy*dy );
								if( dis < checkSize )
									th[xv][y] += tp[ xv + checkSize + dx ][ y + checkSize + dy ];
							}
					}
					System.out.println( xv );
				}
			} );
		}
		
		try {
			s.shutdown();
			s.awaitTermination( 1, TimeUnit.DAYS );
		} catch ( InterruptedException ex ) {
			
		}
		
		int max = 0;
		int min = Integer.MAX_VALUE;
		for( int x = 0; x < fw; x++ ) {
			for( int y = 0; y < fh; y++ ) {
				max = Math.max( th[x][y], max );
				min = Math.min( th[x][y], min );
			}
			System.out.println( "Maxmin" + x );
		}
		
		double c = .5 / (max - min);
		for( int x = 0; x < th.length; x++ ) {
			for( int y = 0; y < th[0].length; y++ ) {
				double k = ((double)(th[x][y] - min) * c);
				heightMap[x][y] = (float)k;
			}
			System.out.println( "pic" + x );
		}
	}
	
	public void renderThis() {
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
		
		GL11.glPushMatrix();
		
		rotation += (float)Math.PI*2f / (60f * 4f);
		rotation %= (float)Math.PI*2f;
		
		final float dis = 2;
		GLU.gluLookAt( (float)Math.cos( rotation )*dis, .5f, (float)Math.sin( rotation )*dis, 0, 0, 0, 0, 1, 0 );
		
		
		TextureUtil.bind( textures.PLAIN );
		for( int x = 0; x < 100; x++ )
			for( int y = 0; y < 100; y++ )
				tile[x][y].renderThis();
		
		GL11.glPopMatrix();
		
	}
	
}
